/**
 * 报表设计公司(2011)
 */
package com.reportgear.report.view;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.reportgear.report.model.ReportModel;
import com.reportgear.report.model.SalaryReportModel;
import com.reportgear.report.model.cell.Cell;
import com.reportgear.report.model.cell.DefaultCell;
import com.reportgear.report.model.cell.style.Style;
import com.reportgear.report.view.grid.DynamicScrollBar;
import com.reportgear.report.view.grid.Grid;
import com.reportgear.report.view.grid.GridColumnHeader;
import com.reportgear.report.view.grid.GridCornor;
import com.reportgear.report.view.grid.GridRowHeader;
import com.reportgear.report.view.grid.selection.GridSelection;
import com.reportgear.report.view.grid.selection.Selection;
import com.reportgear.report.view.grid.util.PaintUtils;
import com.reportgear.report.view.layout.WorkSheetLayout;

/**
 * Cell报表设计与显示面板
 * 
 * @version 1.0 2011-3-14
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since ANNCSR 2.0
 */
public class JWorksheet extends JPanel {
	private static Logger logger = LoggerFactory.getLogger(JWorksheet.class.getName());
	// 报表模型
	private ReportModel reportModel;
	// 表格选择模型
	private GridSelection gridSelection;
	// 网格列头可见性
	private boolean columnHeaderVisible = true;
	// 网格行头可见性
	private boolean rowHeaderVisible = true;
	// 网格
	private Grid grid;
	// 网格行头
	private GridRowHeader gridRowHeader;
	// 网格列头
	private GridColumnHeader gridColumnHeader;
	// 左上角
	private GridCornor gridCorner;
	// 垂直滚动条
	private JScrollBar verScrollBar;
	// 水平滚动条
	private JScrollBar horScrollBar;

	// 水平开始值，起始列index，0 开始,列滚动条计算
	private int horiBeginValue = 0;
	// 水平值范围，显示列数,列头计算
	private int horiValueExtend = 0;
	// 垂直开始值，起始行index，0 开始，行滚动条计算
	private int vertBeginValue = 0;
	// 垂直开始值范围，显示行数，行头计算
	private int vertValueExtend = 0;

	public JWorksheet(ReportModel model) {
		this.reportModel = model;

		this.initComponents();

		this.initParameters();
	}

	/**
	 * 初始化参数
	 */
	private void initParameters() {
	}

	// 初始化视图
	private void initComponents() {
		this.setLayout(new WorkSheetLayout());
		this.gridSelection = new GridSelection();

		this.grid = new Grid(this);
		this.gridColumnHeader = new GridColumnHeader(this);
		this.gridRowHeader = new GridRowHeader(this);
		this.gridCorner = new GridCornor(this);
		this.verScrollBar = new DynamicScrollBar(JScrollBar.VERTICAL, this);
		this.horScrollBar = new DynamicScrollBar(JScrollBar.HORIZONTAL, this);

		this.add(WorkSheetLayout.GRID_CORNOR, this.gridCorner);
		this.add(WorkSheetLayout.GRID_COLUMN_HEADER, this.gridColumnHeader);
		this.add(WorkSheetLayout.GRID_ROW_HEADER, this.gridRowHeader);
		this.add(WorkSheetLayout.GRID, this.grid);
		this.add(WorkSheetLayout.VER_SCROLLBAR, this.verScrollBar);
		this.add(WorkSheetLayout.HOR_SCROLLBAR, this.horScrollBar);
	}

	/**
	 * 获取工作簿对应的模型
	 * 
	 * @return 报表模型
	 */
	public ReportModel getReportModel() {
		return this.reportModel;
	}

	/**
	 * 设置报表模型
	 * 
	 * @param reportModel
	 *            报表模型
	 */
	public void setReportModel(ReportModel reportModel) {
		this.reportModel = reportModel;
	}

	/**
	 * 停止编辑
	 */
	public void stopEditing() {
		this.grid.stopEditing();
	}

	/**
	 * 设置是否显示网格线
	 * 
	 * @param showGridLine
	 *            是否显示网格线
	 */
	public void setShowGridLine(boolean showGridLine) {
		this.grid.setShowGridLine(showGridLine);
	}

	/**
	 * @return 是否显示网格线
	 */
	public boolean isShowGridLines() {
		return this.grid.isShowGridLine();
	}

	/**
	 * 数据改变
	 */
	public void fireReportDataChanged() {
		// logger.info("fireReportDataChanged");
	}

	/**
	 * 选择集改变
	 */
	public void fireGridSelectionChanged() {
		// logger.info("fireGridSelectionChanged");
	}

	/**
	 * 设置网格列头是否可见
	 * 
	 * @param columnHeaderVisible
	 *            值
	 */
	public void setColumnHeaderVisible(boolean columnHeaderVisible) {
		this.columnHeaderVisible = columnHeaderVisible;
		this.gridColumnHeader.setVisible(columnHeaderVisible);
	}

	/**
	 * @return 列头是否可见
	 */
	public boolean isColumnHeaderVisible() {
		return columnHeaderVisible;
	}

	/**
	 * 设置网格行头是否可见
	 * 
	 * @param rowHeaderVisible
	 *            设置值
	 */
	public void setRowHeaderVisible(boolean rowHeaderVisible) {
		this.rowHeaderVisible = rowHeaderVisible;
		this.gridRowHeader.setVisible(columnHeaderVisible);
	}

	/**
	 * @return 网格行头是否可见
	 */
	public boolean isRowHeaderVisible() {
		return rowHeaderVisible;
	}

	/**
	 * @return 获取列头
	 */
	public GridColumnHeader getGridColumnHeader() {
		return this.gridColumnHeader;
	}

	/**
	 * @return 获取行头
	 */
	public GridRowHeader getGridRowHeader() {
		return this.gridRowHeader;
	}

	/**
	 * 设置水平开始列数
	 * 
	 * @param horiBeginValue
	 *            值
	 */
	public void setHoriBeginValue(int horiBeginValue) {
		this.horiBeginValue = horiBeginValue;

		this.refresh();
	}

	/**
	 * 
	 * @return 水平开始列数(0 based)
	 */
	public int getHoriBeginValue() {
		return horiBeginValue;
	}

	/**
	 * 设置水平显示列数
	 * 
	 * @param horiValueExtend
	 *            值
	 */
	public void setHoriValueExtend(int horiValueExtend) {
		this.horiValueExtend = horiValueExtend;
	}

	/**
	 * 
	 * @return 水平显示列数
	 */
	public int getHoriValueExtend() {
		return horiValueExtend;
	}

	/**
	 * 设置垂直开始行数
	 * 
	 * @param vertBeginValue
	 *            垂直开始行
	 */
	public void setVertBeginValue(int vertBeginValue) {
		this.vertBeginValue = vertBeginValue;

		this.repaint();
	}

	/**
	 * 
	 * @return 垂直开始行(0 based)
	 */
	public int getVertBeginValue() {
		return vertBeginValue;
	}

	/**
	 * 设置垂直显示行数
	 * 
	 * @param vertValueExtend
	 *            值
	 */
	public void setVertValueExtend(int vertValueExtend) {
		this.vertValueExtend = vertValueExtend;
	}

	/**
	 * 
	 * @return 垂直显示行数
	 */
	public int getVertValueExtend() {
		return vertValueExtend;
	}

	/**
	 * @return 表格选择模型
	 */
	public GridSelection getGridSelection() {
		return gridSelection;
	}

	/**
	 * 获取行数
	 * 
	 * @return
	 */
	public int getRowCount() {
		return this.reportModel.getRowCount();
	}

	/**
	 * 获取列数
	 * 
	 * @return
	 */
	public int getColumnCount() {
		return this.reportModel.getColumnCount();
	}

	/**
	 * @return the verScrollBar
	 */
	public JScrollBar getVerScrollBar() {
		return verScrollBar;
	}

	public void setVerScrollBar(JScrollBar verScrollBar) {
		this.verScrollBar = verScrollBar;
	}

	public JScrollBar getHorScrollBar() {
		return horScrollBar;
	}

	public void setHorScrollBar(JScrollBar horScrollBar) {
		this.horScrollBar = horScrollBar;
	}

	/**
	 * 绘制单元格：自动判断是否要绘制
	 * 
	 * @param g2
	 *            图形对象
	 * @param column
	 *            列
	 * @param row
	 *            行
	 */
	public void paintCell(Graphics2D g2, int column, int row) {
		paintCell(g2, column, row, grid.getGridLineColor());
	}

	/**
	 * 绘制单元格：自动判断是否要绘制
	 * 
	 * @param g2
	 *            图形对象
	 * @param column
	 *            列
	 * @param row
	 *            行
	 * @param borderColor
	 *            边框颜色
	 */
	public void paintCell(Graphics2D g2, int column, int row, Color borderColor) {
		Cell cell = reportModel.getCell(column, row);

		if (cell == null) {
			return;
		}
		if (cell.isMerged()) {
			return;
		}

		Rectangle rect = reportModel.getCellRectangle(this, cell);

		// 合并的单元格
		if (this.isShowGridLines() && ((cell.getColumnSpan() > 1) || (cell.getRowSpan() > 1))) {
			g2.setPaint(Color.WHITE);
			g2.fill(rect);
			g2.setColor(borderColor);
			g2.draw(rect);
		}

		PaintUtils.paintCellElement(g2, cell, rect);
	}

	/**
	 * 绘制单元格元素类型标志
	 * 
	 * @param g2
	 *            图形对象
	 * @param column
	 *            列
	 * @param row
	 *            行
	 */
	public void paintCellElementFlag(Graphics2D g2, int column, int row) {
		// DefaultCell cell = reportModel.getCell(column, row);
		//
		// // if (cell.isMerged()) {
		// // return;
		// // }
		//
		// Rectangle rect = reportModel.getCellRectangle(column, row);
		//
		// PaintUtils.paintCellElementFlag(g2, cell, rect);
	}

	/**
	 * 获取焦点
	 */
	public void setFocus() {
		this.requestFocus();
	}

	/**
	 * 获取当前活动单元格
	 * 
	 * @return 当前活动单元格
	 */
	public DefaultCell getActiveCell() {
		Selection sel = gridSelection.getEditSelection();
		if (sel != null) {
			Cell ci = this.reportModel.getCell(sel);
			if (ci instanceof DefaultCell) {
				return ((DefaultCell) ci);
			}
		}

		return null;
	}

	/**
	 * 返回当前编辑单元格Style
	 * 
	 * @return 当前编辑单元格Style
	 */
	public Style getActiveCellStyle() {
		DefaultCell cell = this.getActiveCell();

		if (cell == null) {
			return Style.DEFAULT_STYLE;
		} else {
			return cell.getStyle();
		}
	}

	/**
	 * 合并单元格
	 * 
	 * @param columnFrom
	 *            开始列
	 * @param rowFrom
	 *            开始行
	 * @param columnSpan
	 *            列跨度
	 * @param rowSpan
	 *            行跨度
	 */
	public void mergeCell(int columnFrom, int rowFrom, int columnSpan, int rowSpan) {
		if (getGridSelection().getCellSelectionCount() > 1) {
			return;
		}

		this.reportModel.mergeCell(columnFrom, rowFrom, columnSpan, rowSpan);
		getGridSelection().setEditBounds(columnFrom, rowFrom, columnSpan, rowSpan);

		updateUI();
	}

	/**
	 * 合并单元格
	 * 
	 * @param rect
	 *            矩形区域
	 */
	public void mergeCell(Selection selection) {
		this.mergeCell(selection.getColumn(), selection.getRow(), selection.getColumSpan(), selection.getRowSpan());
	}

	/**
	 * 合并选择的单元格
	 * 
	 * @return
	 */
	public void mergeCell() {
		this.mergeCell(this.getGridSelection().getLastCellSelection());
	}

	/**
	 * 拆散单元格
	 * 
	 * @param columnFrom
	 *            开始列
	 * @param rowFrom
	 *            开始行
	 * @param columnSpan
	 *            列跨度
	 * @param rowSpan
	 *            行跨度
	 */
	public void unmergeCell(int columnFrom, int rowFrom, int columnSpan, int rowSpan) {
		this.reportModel.unmergeCell(columnFrom, rowFrom, columnSpan, rowSpan);
		this.getGridSelection().setEditBounds(columnFrom, rowFrom, 1, 1);

		updateUI();
	}

	/**
	 * 拆散单元格
	 * 
	 * @param rect
	 *            区域
	 */
	public void unmergeCell(Selection selection) {
		this.unmergeCell(selection.getColumn(), selection.getRow(), selection.getColumSpan(), selection.getRowSpan());
	}

	/**
	 * 取消单元格合并
	 * 
	 * @return
	 */
	public void unmergeCell() {
		this.unmergeCell(getGridSelection().getLastCellSelection());
	}

	public List<Cell> getSelectedCells() {
		List<Cell> result = new ArrayList<Cell>();
		for (Selection rect : getGridSelection().getCellSelectionList()) {
			for (int i = 0, clen = rect.getColumSpan(); i < clen; i++) {
				for (int j = 0, rlen = rect.getRowSpan(); j < rlen; j++) {
					result.add(this.reportModel.getCell(rect.getColumn() + i, rect.getRow() + j));
				}
			}
		}

		return result;
	}

	public Grid getGrid() {
		return this.grid;
	}

	/**
	 * @return 最后一个选择集
	 */
	public Selection getLastCellSelection() {
		return this.getGridSelection().getLastCellSelection();
	}

	/**
	 * 工作薄刷新，调用此函数更新组件
	 */
	public void refresh() {
		this.repaint();
	}

	/**
	 * 设置单元格对象值
	 * 
	 * @param column
	 *            列
	 * @param row
	 *            行
	 * @param value
	 *            值
	 */
	public void setCellValue(int column, int row, Object value) {
		this.reportModel.setCellValue(column, row, value);
	}

	/**
	 * 设置Grid菜单
	 * 
	 * @param gridActionMenu
	 *            Grid菜单
	 */
	public void setGridActionMenu(JPopupMenu gridActionMenu) {
		this.grid.setGridActionMenu(gridActionMenu);
	}
}
